package cn.uway.utils;

import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class DES3Utils {

	 //定义加密算法，有DES、DESede(即3DES)、Blowfish
       private static final String Algorithm = "DESede";    
	   private static final String PASSWORD_CRYPT_KEY = "wnlbs123456";
	     
	     
     /**
      * 加密方法
      * @param src 源数据的字节数组
      * @return 
      */
     public static byte[] encode(byte[] src) {
         try {
              SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);    //生成密钥
              Cipher c1 = Cipher.getInstance(Algorithm);    //实例化负责加密/解密的Cipher工具类
              c1.init(Cipher.ENCRYPT_MODE, deskey);    //初始化为加密模式
              return c1.doFinal(src);
          } catch (NoSuchAlgorithmException e1) {
              e1.printStackTrace();
          } catch (NoSuchPaddingException e2) {
              e2.printStackTrace();
          } catch (Exception e3) {
              e3.printStackTrace();
          }
          return null;
      }
	
      /**
      * 解密函数
      * @param src 密文的字节数组
      * @return
      */
      public static byte[] decode(byte[] src) {      
         try {
             SecretKey deskey = new SecretKeySpec(build3DesKey(PASSWORD_CRYPT_KEY), Algorithm);
             Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);    //初始化为解密模式
             return c1.doFinal(src);
         } catch (NoSuchAlgorithmException e1) {
             e1.printStackTrace();
         } catch (NoSuchPaddingException e2) {
             e2.printStackTrace();
         } catch (Exception e3) {
             e3.printStackTrace();
         }
         return null;
      }
	     
	    
      /*
       * 根据字符串生成密钥字节数组 
       * @param keyStr 密钥字符串
       * @return 
       */
      public static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException{
         byte[] key = new byte[24];    //声明一个24位的字节数组，默认里面都是0
         byte[] temp = keyStr.getBytes("UTF-8");    //将字符串转成字节数组
         
         /*
          * 执行数组拷贝
          * System.arraycopy(源数组，从源数组哪里开始拷贝，目标数组，拷贝多少位)
          */
         if(key.length > temp.length){
             //如果temp不够24位，则拷贝temp数组整个长度的内容到key数组中
             System.arraycopy(temp, 0, key, 0, temp.length);
         }else{
             //如果temp大于24位，则拷贝temp数组24个长度的内容到key数组中
            System.arraycopy(temp, 0, key, 0, key.length);
         }
         return key;
      } 
	     
      private static String byte2hex(byte[] b) {
    	    StringBuffer hs = new StringBuffer();
    	    String stmp = "";
    	    for (int n = 0; n < b.length; n++) {
    	      stmp = Integer.toHexString(b[n] & 0xFF);
    	      if (stmp.length() == 1)
    	        hs = hs.append("0").append(stmp);
    	      else {
    	        hs = hs.append(stmp);
    	      }
    	    }
    	    return hs.toString().toUpperCase();
      }
	     
     /**
      * 十六进制转换字符串
      * @param hex String 十六进制
      * @return String 转换后的字符串
      */
      public static byte[] hex2byte(String hex) {
         String digital = "0123456789ABCDEF";
         char[] hex2char = hex.toCharArray();
         byte[] bytes = new byte[hex.length() / 2];
         int temp;
         for (int i = 0; i < bytes.length; i++) {
             temp = digital.indexOf(hex2char[2 * i]) * 16;
             temp += digital.indexOf(hex2char[2 * i + 1]);
             bytes[i] = (byte) (temp & 0xff);
         }
         return bytes;
      }
	     
      /**
      * 字符串转java字节码
      * @param
      * @return
      */
      public static byte[] hex2byte_2(String hex) {
         byte [] b = hex.getBytes();
         byte[] b2 = new byte[b.length / 2];
         for (int n = 0; n < b.length; n += 2) {
             String item = new String(b, n, 2);
             // 两位一组，表示一个字节,把这样表示的16进制字符串，还原成一个进制字节
  
             b2[n / 2] = (byte) Integer.parseInt(item, 16);
         }
         b = null;
         return b2;
      }
	     
      public static String encode(String source){
    	 //加密
         byte[] secretArr=null;
		 try {
			 secretArr = encode(source.getBytes("UTF-8"));
		 } catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		 } 
         return byte2hex(secretArr);
      }
     
      public static String decode(String encodeStr){
    	 //加密
         byte[] secretArr = hex2byte(encodeStr); 
         byte[] sourceArr = decode(secretArr);
         try {
			return new String(sourceArr,"UTF-8");
		 } catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		 }
         return null;
      }
	     
      public static void main(String[] args) {
    	 long t = System.currentTimeMillis();
         String msg = "3DES加密解密案例";
         
         System.out.println("【加密前】：" + msg);	         
         String encodeStr = DES3Utils.encode(msg);
         System.out.println("【加密后】：" + encodeStr);
         
         //解密
         String oldStr = DES3Utils.decode(encodeStr);  
         System.out.println("【解密后】：" + oldStr);
         
         long t1 = System.currentTimeMillis();
         System.out.println(t1-t);
         
         System.out.println(PASSWORD_CRYPT_KEY.length());
     }
}
